package pl.edu.agh.jemo.evolution.objfunc.impl;

import java.math.BigDecimal;

import javax.swing.JPanel;

import pl.edu.agh.jemo.evolution.genotype.Genotype;
import pl.edu.agh.jemo.evolution.objfunc.ClassicObjectiveFunction;
import pl.edu.agh.jemo.evolution.specimen.Specimen;

public class SchweffelObjFunc extends ClassicObjectiveFunction {

	private final String SCHWEFFEL_GNUPLOT_FORMULA;

	public static final BigDecimal[][] EXTREMA = {{BigDecimal.valueOf(420.969), BigDecimal.valueOf(-500.0)},
        {BigDecimal.valueOf(203.814), BigDecimal.valueOf(-500.0)},
        {BigDecimal.valueOf(65.5479), BigDecimal.valueOf(-500.0)},
        {BigDecimal.valueOf(-25.8774), BigDecimal.valueOf(-500.0)},
        {BigDecimal.valueOf(-124.829), BigDecimal.valueOf(-500.0)},
        {BigDecimal.valueOf(-302.525), BigDecimal.valueOf(-500.0)},
        {BigDecimal.valueOf(-500.0), BigDecimal.valueOf(-500.0)},
        {BigDecimal.valueOf(-500.0), BigDecimal.valueOf(-302.525)},
        {BigDecimal.valueOf(-500.0), BigDecimal.valueOf(-124.829)},
        {BigDecimal.valueOf(-500.0), BigDecimal.valueOf(-25.8774)},
        {BigDecimal.valueOf(-500.0), BigDecimal.valueOf(65.5479)},
        {BigDecimal.valueOf(-500.0), BigDecimal.valueOf(203.814)},
        {BigDecimal.valueOf(-500.0), BigDecimal.valueOf(420.969)},
        {BigDecimal.valueOf(-302.525), BigDecimal.valueOf(420.969)},
        {BigDecimal.valueOf(-124.829), BigDecimal.valueOf(420.969)},
        {BigDecimal.valueOf(-25.8774), BigDecimal.valueOf(420.969)},
        {BigDecimal.valueOf(5.2392), BigDecimal.valueOf(420.969)},
        {BigDecimal.valueOf(65.5479), BigDecimal.valueOf(420.969)},
        {BigDecimal.valueOf(203.814), BigDecimal.valueOf(420.969)},
        {BigDecimal.valueOf(420.969), BigDecimal.valueOf(420.969)},
        {BigDecimal.valueOf(420.969), BigDecimal.valueOf(203.814)},
        {BigDecimal.valueOf(420.969), BigDecimal.valueOf(65.5479)},
        {BigDecimal.valueOf(420.969), BigDecimal.valueOf(5.2392)},
        {BigDecimal.valueOf(420.969), BigDecimal.valueOf(-25.8774)},
        {BigDecimal.valueOf(420.969), BigDecimal.valueOf(-124.829)},
        {BigDecimal.valueOf(420.969), BigDecimal.valueOf(-302.525)},
        {BigDecimal.valueOf(203.814), BigDecimal.valueOf(-302.525)},
        {BigDecimal.valueOf(65.5479), BigDecimal.valueOf(-302.525)},
        {BigDecimal.valueOf(5.2392), BigDecimal.valueOf(-302.525)},
        {BigDecimal.valueOf(-25.8774), BigDecimal.valueOf(-302.525)},
        {BigDecimal.valueOf(-124.829), BigDecimal.valueOf(-302.525)},
        {BigDecimal.valueOf(-302.525), BigDecimal.valueOf(-302.525)},
        {BigDecimal.valueOf(-302.525), BigDecimal.valueOf(-124.829)},
        {BigDecimal.valueOf(-302.525), BigDecimal.valueOf(-25.8774)},
        {BigDecimal.valueOf(-302.525), BigDecimal.valueOf(5.2392)},
        {BigDecimal.valueOf(-302.525), BigDecimal.valueOf(65.5479)},
        {BigDecimal.valueOf(-302.525), BigDecimal.valueOf(203.814)},
        {BigDecimal.valueOf(-124.829), BigDecimal.valueOf(203.814)},
        {BigDecimal.valueOf(-25.8774), BigDecimal.valueOf(203.814)},
        {BigDecimal.valueOf(5.2392), BigDecimal.valueOf(203.814)},
        {BigDecimal.valueOf(65.5479), BigDecimal.valueOf(203.814)},
        {BigDecimal.valueOf(203.814), BigDecimal.valueOf(203.814)},
        {BigDecimal.valueOf(203.814), BigDecimal.valueOf(65.5479)},
        {BigDecimal.valueOf(203.814), BigDecimal.valueOf(5.2392)},
        {BigDecimal.valueOf(203.814), BigDecimal.valueOf(-25.8774)},
        {BigDecimal.valueOf(203.814), BigDecimal.valueOf(-124.829)},
        {BigDecimal.valueOf(65.5479), BigDecimal.valueOf(-124.829)},
        {BigDecimal.valueOf(5.2392), BigDecimal.valueOf(-124.829)},
        {BigDecimal.valueOf(-25.8774), BigDecimal.valueOf(-124.829)},
        {BigDecimal.valueOf(-124.829), BigDecimal.valueOf(-124.829)},
        {BigDecimal.valueOf(-124.829), BigDecimal.valueOf(-25.8774)},
        {BigDecimal.valueOf(-124.829), BigDecimal.valueOf(5.2392)},
        {BigDecimal.valueOf(-124.829), BigDecimal.valueOf(65.5479)},
        {BigDecimal.valueOf(-25.8774), BigDecimal.valueOf(65.5479)},
        {BigDecimal.valueOf(5.2392), BigDecimal.valueOf(65.5479)},
        {BigDecimal.valueOf(65.5479), BigDecimal.valueOf(65.5479)},
        {BigDecimal.valueOf(65.5479), BigDecimal.valueOf(5.2392)},
        {BigDecimal.valueOf(65.5479), BigDecimal.valueOf(-25.8774)},
        {BigDecimal.valueOf(5.2392), BigDecimal.valueOf(-25.8774)},
        {BigDecimal.valueOf(-25.8774), BigDecimal.valueOf(-25.8774)},
        {BigDecimal.valueOf(-25.8774), BigDecimal.valueOf(5.2392)},
        {BigDecimal.valueOf(5.2392), BigDecimal.valueOf(5.2392)}};

	@Override
	public Double calculateValue(Specimen specimen) {
		final Genotype[] genotype = specimen.getGenotype();
		double currentFitness = 2*418.9829 - genotype[0].asDouble()*Math.sin(Math.sqrt(Math.abs(genotype[0].asDouble()))) - genotype[1].asDouble()*Math.sin(Math.sqrt(Math.abs(genotype[1].asDouble())));
		return -currentFitness;
	}

	@Override
	public boolean isInDomain(Specimen specimen) {
		return (((-500 < specimen.getGenotype()[0].asDouble()) && (500 > specimen
				.getGenotype()[0].asDouble())) && ((-500 < specimen.getGenotype()[1].asDouble()) && (500 > specimen
				.getGenotype()[1].asDouble())));
	}

	@Override
	public Double[][] getBoundaries() {
		return new Double[][] {{-500d,500d},{-500d,500d}};
	}

	@Override
	public int getDimensions() {
		return 2;
	}

	public SchweffelObjFunc() {
		SCHWEFFEL_GNUPLOT_FORMULA = "2*418.9829 - x * sin(sqrt(abs(x))) - y * sin(sqrt(abs(y)))";
	}

	@Override
	public String getFormula() {
		return SCHWEFFEL_GNUPLOT_FORMULA;
	}

	@Override
	public JPanel getConfigPanel() {
		// TODO Manio zaimplementuj to wreszcie!!!
		return null;
	}

	@Override
	public Double getMaxValue() {
		return 0d;
	}
	
	@Override
	public Double getMinValue() {
		return -1800d;
	}
}
